Български

Научете как да изграждате бекенд без сървър с Next.js API Routes. Ръководството покрива основна настройка, удостоверяване, съхранение на данни и други.

API маршрути в Next.js: Изграждане на вашия бекенд с лекота

Next.js направи революция във фронтенд разработката със своите мощни функции и интуитивна структура. Но знаехте ли, че може значително да опрости и разработката на бекенд? API маршрутите (API Routes) в Next.js ви позволяват да създавате безсървърни (serverless) API ендпойнти директно във вашето Next.js приложение, като в много случаи премахват необходимостта от отделен бекенд сървър. Това подробно ръководство ще ви преведе през процеса на изграждане на стабилен и мащабируем бекенд с помощта на Next.js API Routes.

Какво представляват API маршрутите в Next.js?

API маршрутите са безсървърни функции, които създавате в директорията /pages/api във вашия Next.js проект. Тези функции обработват входящи HTTP заявки и връщат отговори, точно както традиционен бекенд API. Ключовата разлика е, че те се разгръщат като безсървърни функции, което означава, че не е нужно да управлявате сървъри или инфраструктура.

Мислете за тях като за леки бекенд функции при поискване, които са безпроблемно интегрирани с вашия Next.js фронтенд.

Предимства на използването на Next.js API Routes

Първи стъпки с Next.js API Routes

Нека създадем прост API маршрут, който връща JSON отговор. Първо, уверете се, че имате настроен Next.js проект. Ако не, създайте такъв с помощта на:

npx create-next-app my-app
cd my-app

Сега създайте файл с име hello.js в директорията /pages/api:

// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ name: 'John Doe' })
}

Този код дефинира прост API маршрут, който отговаря с JSON обект, съдържащ името „John Doe“. За достъп до този API маршрут, стартирайте вашия Next.js сървър за разработка:

npm run dev

След това отворете браузъра си и отидете на http://localhost:3000/api/hello. Трябва да видите следния JSON отговор:

{"name": "John Doe"}

Разбиране на handler-а на API маршрута

Функцията handler във вашия API маршрут получава два аргумента:

Можете да използвате тези обекти, за да обработвате различни типове заявки, да четете данни от тялото на заявката, да задавате хедъри на отговора и да изпращате различни типове отговори.

Обработка на различни HTTP методи

Можете да използвате свойството req.method, за да определите HTTP метода на входящата заявка и да обработвате различните методи съответно. Например:

// pages/api/method.js
export default function handler(req, res) {
  if (req.method === 'GET') {
    // Обработка на GET заявка
    res.status(200).json({ message: 'Това е GET заявка' })
  } else if (req.method === 'POST') {
    // Обработка на POST заявка
    res.status(200).json({ message: 'Това е POST заявка' })
  } else {
    // Обработка на други методи
    res.status(405).json({ message: 'Методът не е разрешен' })
  }
}

В този пример API маршрутът обработва както GET, така и POST заявки. Ако методът на заявката е GET, той отговаря с JSON обект, съдържащ съобщението „Това е GET заявка“. Ако методът на заявката е POST, той отговаря с JSON обект, съдържащ съобщението „Това е POST заявка“. Ако методът на заявката е друг, той отговаря с грешка 405 Method Not Allowed (Методът не е разрешен).

Четене на данни от тялото на заявката

При POST, PUT и PATCH заявки често се налага да четете данни от тялото на заявката. Next.js предоставя вградена поддръжка за парсване на JSON и URL-кодирани тела на заявки. За да парснете JSON тяло на заявка, можете да използвате свойството req.body. Например:

// pages/api/post.js
export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { name, email } = req.body

    // Обработка на данните
    console.log('Име:', name)
    console.log('Имейл:', email)

    res.status(200).json({ message: 'Данните са получени успешно' })
  } else {
    res.status(405).json({ message: 'Методът не е разрешен' })
  }
}

За да тествате този API маршрут, можете да използвате инструмент като Postman или curl, за да изпратите POST заявка с JSON тяло:

curl -X POST -H "Content-Type: application/json" -d '{"name": "Jane Doe", "email": "jane.doe@example.com"}' http://localhost:3000/api/post

Задаване на хедъри на отговора

Можете да използвате метода res.setHeader(), за да зададете хедъри на отговора. Това е полезно за задаване на типа на съдържанието, контрол на кеширането и друга важна информация. Например:

// pages/api/headers.js
export default function handler(req, res) {
  res.setHeader('Content-Type', 'application/json')
  res.setHeader('Cache-Control', 's-maxage=3600')
  res.status(200).json({ message: 'Hello, world!' })
}

В този пример API маршрутът задава хедъра Content-Type на application/json, което показва, че отговорът е JSON обект. Той също така задава хедъра Cache-Control на s-maxage=3600, което казва на браузъра и CDN да кешират отговора за до 1 час.

Обработка на грешки

Важно е да обработвате грешките елегантно във вашите API маршрути. Можете да използвате try-catch блокове, за да улавяте изключения и да изпращате подходящи отговори за грешки към клиента. Например:

// pages/api/error.js
export default async function handler(req, res) {
  try {
    // Симулиране на грешка
    throw new Error('Нещо се обърка')
  } catch (error) {
    console.error(error)
    res.status(500).json({ message: 'Вътрешна грешка на сървъра' })
  }
}

В този пример API маршрутът симулира грешка, като хвърля нов Error обект. Блокът catch улавя грешката, записва я в конзолата и изпраща отговор 500 Internal Server Error (Вътрешна грешка на сървъра) към клиента. Обмислете използването на надеждна система за регистриране (logging) като Sentry или Datadog за производствени среди.

Свързване с база данни

Един от най-често срещаните случаи на употреба на API маршрути е свързването с база данни. Next.js API Routes се интегрират безпроблемно с различни бази данни, включително:

Ето пример как да се свържете с база данни MongoDB в API маршрут на Next.js:

// pages/api/mongodb.js
import { MongoClient } from 'mongodb'

const uri = process.env.MONGODB_URI
const options = {}

let client
let clientPromise

if (!process.env.MONGODB_URI) {
  throw new Error('Моля, добавете вашия Mongo URI в .env.local')
}

if (process.env.NODE_ENV === 'development') {
  // В режим на разработка използвайте глобална променлива, така че стойността
  // да се запази при презареждане на модули, причинено от HMR (Hot Module Replacement).
  if (!global._mongoClientPromise) {
    client = new MongoClient(uri, options)
    global._mongoClientPromise = client.connect()
  }
  clientPromise = global._mongoClientPromise
} else {
  // В производствен режим е най-добре да не се използва глобална променлива.
  client = new MongoClient(uri, options)
  clientPromise = client.connect()
}

// Експортирайте MongoClient promise с обхват на модула. Като направите това в
// отделен модул, клиентът може безопасно да се използва повторно в множество
// функции. Вижте: https://github.com/vercel/next.js/blob/canary/examples/with-mongodb/lib/mongodb.js
export default async function handler(req, res) {
  try {
    const client = await clientPromise
    const db = client.db(process.env.MONGODB_DB)
    const collection = db.collection('users')

    const users = await collection.find({}).toArray()

    res.status(200).json({ users })
  } catch (e) {
    console.error(e)
    res.status(500).json({ message: 'Неуспешно извличане на потребители' })
  }
}

Преди да стартирате този код, уверете се, че имате инсталиран пакета mongodb:

npm install mongodb

Трябва също така да зададете променливите на средата MONGODB_URI и MONGODB_DB. Тези променливи трябва да бъдат дефинирани във вашия файл .env.local (или в настройките за променливи на средата на вашия хостинг доставчик за производство). MONGODB_URI съдържа низа за връзка (connection string) към вашата MongoDB база данни, а MONGODB_DB указва името на базата данни.

Удостоверяване и оторизация

Защитата на вашите API маршрути е от решаващо значение за сигурността. Next.js API Routes могат да бъдат защитени с помощта на различни техники за удостоверяване и оторизация, включително:

Ето пример как да защитите API маршрут, използвайки JWT удостоверяване:

// pages/api/protected.js
import jwt from 'jsonwebtoken'

const secret = process.env.JWT_SECRET

export default function handler(req, res) {
  const token = req.headers.authorization?.split(' ')[1]

  if (!token) {
    return res.status(401).json({ message: 'Неупълномощен достъп' })
  }

  try {
    const decoded = jwt.verify(token, secret)
    // Обектът "decoded" съдържа потребителската информация, вградена в токена
    // Например: const userId = decoded.userId;

    // Продължаване на обработката на заявката
    res.status(200).json({ message: 'Достъпът до защитения ресурс е успешен' })
  } catch (error) {
    return res.status(401).json({ message: 'Невалиден токен' })
  }
}

Преди да стартирате този код, уверете се, че имате инсталиран пакета jsonwebtoken:

npm install jsonwebtoken

Трябва също така да зададете променливата на средата JWT_SECRET. Това трябва да бъде силен, произволно генериран таен ключ, който се използва за подписване и проверка на JWT. Съхранявайте го сигурно и никога не го излагайте във вашия клиентски код.

Мидълуер (Middleware)

Въпреки че Next.js не предлага традиционен мидълуер за API маршрути по същия начин като Express.js, можете да постигнете подобна функционалност, като обвиете вашите handler-и на API маршрути с функции за многократна употреба. Това ви позволява да изпълнявате задачи като:

Ето пример как да създадете прост мидълуер за регистриране:

// utils/middleware.js
export function withLogging(handler) {
  return async function(req, res) {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`)
    return handler(req, res)
  }
}

За да използвате този мидълуер, просто обвийте вашия handler на API маршрута с функцията withLogging:

// pages/api/logged.js
import { withLogging } from '../../utils/middleware'

async function handler(req, res) {
  res.status(200).json({ message: 'Тази заявка беше регистрирана' })
}

export default withLogging(handler)

Добри практики за изграждане на Next.js API Routes

Напреднали техники

Фонови задачи

За дълготрайни задачи, които не трябва да блокират отговора на API, обмислете използването на фонови задачи. Можете да използвате библиотеки като BullMQ или Bree, за да управлявате вашите фонови задачи и да ги обработвате асинхронно.

WebSockets

За приложения в реално време можете да използвате WebSockets във вашите Next.js API маршрути. Библиотеки като Socket.IO и ws улесняват установяването на постоянни връзки между клиента и сървъра.

GraphQL

Ако се нуждаете от по-гъвкав и ефективен начин за извличане на данни, обмислете използването на GraphQL. Можете да използвате библиотеки като Apollo Server или Yoga, за да създадете GraphQL API ендпойнт във вашето Next.js приложение.

Заключение

Next.js API Routes предоставят мощен и удобен начин за изграждане на безсървърни бекенди директно във вашето Next.js приложение. Като се възползвате от предимствата на безсървърната архитектура, можете да опростите разработката, да подобрите производителността и да намалите разходите. Независимо дали изграждате проста форма за контакт или сложна платформа за електронна търговия, Next.js API Routes могат да ви помогнат да създадете стабилен и мащабируем бекенд с лекота. Със солидно разбиране на основите и прилагането на добри практики можете да използвате този мощен инструмент за създаване на ефективни, сигурни и глобално достъпни приложения.

API маршрути в Next.js: Изграждане на вашия бекенд с лекота | MLOG